package com.sarnath.sardoop.modules.hbase.reflect;

import java.lang.reflect.Field;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.beanutils.BeanUtils;
import org.apache.hadoop.hbase.util.Bytes;

/**
 * @author yingc
 *将查询结果映射到Bean中
 */
public class HbaseBeanConverter {
	private Map<String, Map<String, String>> fieldMap = new HashMap<>();
	private String keyField = null;
	private Map<String, String> fieldType = new HashMap<>();

	public HbaseBeanConverter(Class cls) {
		for (Field f : cls.getDeclaredFields()) {
			HbaseOrm orm = f.getAnnotation(HbaseOrm.class);
			if (orm != null) {
				if (orm.isKey()) {
					keyField = f.getName();
				} else {
					Map fMap = fieldMap.get(orm.family());
					if (fMap == null) {
						fMap = new HashMap<>();
						fieldMap.put(orm.family(), fMap);
					}
					fMap.put(orm.column(), f.getName());
				}
				fieldType.put(f.getName(), f.getType().getName());
			}
		}
	}

	/**
	 * 字段映射
	 * @param bean
	 * @param familyName
	 * @param columnName
	 * @param value
	 * @throws Exception
	 */
	public void convert(Object bean, String familyName, String columnName, byte[] value) throws Exception {
		String fieldName = fieldMap.get(familyName) != null ? fieldMap.get(familyName).get(columnName) : null;
		if (fieldName != null) {
			BeanUtils.setProperty(bean, fieldName, byteToObj(fieldName,value));
		}
	}
	
	/**
	 * rowkey映射
	 * @param bean
	 * @param value
	 * @throws Exception
	 */
	public void convert(Object bean, byte[] value) throws Exception{
		if(keyField!=null){
			BeanUtils.setProperty(bean, keyField, byteToObj(keyField,value));
		}
	}
	
	private Object byteToObj(String fieldName,byte[] value){
		switch (fieldType.get(fieldName)) {
		case "java.lang.String":
			return Bytes.toString(value);
		case "int":
			return Bytes.toInt(value);
		case "long":
			return Bytes.toLong(value);
		case "boolean":
			return Bytes.toBoolean(value);
		default:
			return value;
		}
	}

	public static void main(String[] args) {
		@SuppressWarnings("unused")
		HbaseBeanConverter c = new HbaseBeanConverter(Test.class);
	}
}

// int
// java.lang.String
// long
// boolean
// [B
// java.util.Date
class Test {
	@HbaseOrm(isKey = true)
	private int id;
	@HbaseOrm(family = "a", column = "a1")
	private String a1;
	@HbaseOrm(family = "a", column = "a2")
	private long a2;
	@HbaseOrm(family = "a", column = "a3")
	private boolean a3;
	@HbaseOrm(family = "a", column = "a4")
	private byte[] a4;
	@HbaseOrm(family = "a", column = "a5")
	private Date a5;

}
